import wx
import os
from decimal import Decimal as Dec
import decimal

from GUIBaseGrid import BaseTable
from DiaTable2 import DiaTable2add, DiaTable2Rate
from DiaTable3 import DiaTable3add
from DiaTable3Changev2 import DiaTable3Change
from DiaTable4 import DiaTable4Add, DiaTable4Change
from DiaTable5 import DiaTable5Add, DiaTable5ChangeRate
from DiaTable4ChangeRates import DiaTable4ChangeRates
from DiaTable1ChangeRates import DiaTable1ChangeRates
from CustSearchCtrl import CustSearchCtrl
from DiaTableFliter import DiaTableFliter

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
class Table_1(BaseTable):

   def __init__(self):
      cols = self.getcollabels()
      super().__init__(cols=cols)

   def getcollabels(self):
      labels = [
            '表格编号', '费用名称', '小型建筑\n工程费', '需要安装的\n设备费', 
            '不需要安装的\n设备、工器具费', '建筑安装\n工程费', '其他费用',
            '预备费', '总价值\n除税价', '总价值\n增值税', '总价值\n含税价', 
            '其中外币\n（ ）'
               ]

      return labels

   def GetCornerLabelValue(self):
      return '序号'

   @staticmethod
   def getsize(string):
      if string == 'rows':
         return
      elif string == 'cols':
         return {1:120, 2:100, 3:100, 4:100, 5:100, 6:100, 7:100, 8:100, 9:100, 10:100, 11:60}
      return 

class Table_2(BaseTable):

   def __init__(self):
      cols = self.getcollabels()
      super().__init__(cols=cols)

   def getcollabels(self):
      labels = [
            '序号·一', '费用名称·一', '依据和计算方法·一', '合计·元·一', 
            '序号·二', '费用名称·二', '依据和计算方法·二', '合计·元·二', 
               ]

      return labels

   def getrowlabels(self):
      labels = []
      for i in range(1,35):
         labels.append(str(i))
      
      return labels

   def GetCornerLabelValue(self):
      return '序列'

   @staticmethod
   def getsize(string):
      if string == 'rows':
         return
      elif string == 'cols':
         return {0:40, 1:200, 2:200, 3:120, 4:40, 5:200, 6:200, 7:120}
      return 

class Table_3(BaseTable):

   def __init__(self):
      cols = self.getcollabels()
      super().__init__(cols=cols)

   def getcollabels(self):
      labels = [
            '定额编号', '项目名称', 
            '单位', '数量', '定额技工', 
            '定额普工', '合计技工', '合计普工', 
            '拆除情况', '系数', '计取说明', 
               ]

      return labels

   def GetCornerLabelValue(self):
      return '序号'

   @staticmethod
   def getsize(string):
      if string == 'rows':
         return
      elif string == 'cols':
         return {
               0:60, 1:420, 2:80, 3:80, 4:70,
               5:70, 6:70, 7:70, 8:70, 9:30,
               10:60,
               }
      return 

class Table_3_2(BaseTable):

   def __init__(self):
      cols = self.getcollabels()
      super().__init__(cols=cols)

   def getcollabels(self):
      labels = [
            '定额编号', '项目名称', 
            '单位', '数量', '机械（仪表）名称', 
            '定额\n消耗量', '定额\n单价', '合计\n消耗量', 
            '合计\n价格', '拆除\n情况', '系数', 
               ]

      return labels

   def GetCornerLabelValue(self):
      return '序号'

   @staticmethod
   def getsize(string):
      if string == 'rows':
         return
      elif string == 'cols':
         return {
               0:60, 1:420, 2:40, 3:40, 4:160,
               5:60, 6:60, 7:80, 8:80, 9:60, 10:30
               }
      return 

class Table_4(BaseTable):

   def __init__(self):
      cols = self.getcollabels()
      super().__init__(cols=cols)

   def getcollabels(self):
      labels = [
            '名称', '规格程式', 
            '单位', '数量', '单价\n除税价', 
            '单价\n增值税', '单价\n含税价', '合计\n除税价', 
            '合计\n增值税', '合计\n含税价', '备注',
               ]

      return labels

   @staticmethod
   def getsize(string):
      if string == 'rows':
         return
      elif string == 'cols':
         return {
               0:180, 1:330, 2:60, 3:60, 4:60,
               5:60, 6:60, 7:80, 8:80, 9:80, 10:70
               }
      return 

   def GetCornerLabelValue(self):
      return '序号'

class Table_5(BaseTable):

   def __init__(self):
      cols = self.getcollabels()
      super().__init__(cols=cols)

   def getcollabels(self):
      labels = [
            '费用名称', '计算依据及方法', 
            '除税价', '增值税', '含税价', 
            '备注'
               ]

      return labels

   def GetCornerLabelValue(self):
      return '序号'

   @staticmethod
   def getsize(string):
      if string == 'rows':
         return
      elif string == 'cols':
         return {
               0:160, 1:360, 2:80, 3:80, 4:80,
               5:160,
               }
      return 



class BudgetPanel(wx.Panel):

   binddict = {
               '表一': 'OnTable1',
               '表二': 'OnTable2',
               '表二（标）': 'OnTable2S',
               '表三甲': 'OnTable3A',
               '表三乙': 'OnTable3B',
               '表三丙': 'OnTable3C',
               '表四设备': 'OnTable4A',
               '表四材料': 'OnTable5B',
               '表五': 'OnTable5',
               }
               
   def __init__(self, parent, table, name, *args, **kwargs):
      # 将table 放入panel中
      # name为唯一名字
      super().__init__(parent)
      self.sizer = wx.BoxSizer(wx.VERTICAL)
      self.table = table
      self.name = name
      self.grid = wx.grid.Grid(self)
      self.grid.name = name
      self.grid.SetTable(table, True)
      cols = table.getsize('cols')
      self.changelabelsize(self.grid, cols=cols)

      self.LastFindLoc = None

      self.InitPop()
      self.grid.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK, self.OnShowPopmenu)
      self.grid.Bind(wx.grid.EVT_GRID_LABEL_RIGHT_CLICK, self.OnShowLabelPopmenu)

      self.SearchCtrl = CustSearchCtrl(self)
      # self.Bind(wx.EVT_TEXT, self.OnSearch, self.SearchCtrl)
      self.Bind(wx.EVT_SEARCH, self.OnSearch, self.SearchCtrl)
      self.grid.Bind(wx.EVT_SET_FOCUS, self.OnActive)

      self.SetSizer(self.sizer)
      self.Fit()
      self.sizer.Add(self.SearchCtrl, 0, wx.EXPAND, 0)
      self.sizer.Add(self.grid, 1, wx.EXPAND|wx.FIXED_MINSIZE, 0)
      self.sizer.Hide(0)

   def OnActive(self, event):
      if hasattr(self, 'Dia'):
         self.Dia.Destroy()
         try:
            del self.Dia
         except:
            pass
      


   def HideRows(self, data, col):
      # data 从DiaTableFilter来，[[row, value],[row, value],....]
      NRows = self.grid.GetNumberRows()
      print(data, col)
      for i in range(NRows):
         if self.grid.GetCellValue(i, col) in data:
            self.grid.ShowRow(i)
         else:
            self.grid.HideRow(i)
      self.OnActive(0)

   def OnShowLabelPopmenu(self, event):
      self.OnActive(0)
      Obj = event.GetEventObject()
      Row = event.GetRow()
      Col = event.GetCol()
      pos = event.GetPosition()
      if Row != -1:
         pass
      else:
         Data = self.table.GetData()
         ColData = []
         for index, v in enumerate(Data):
            ColData.append(v[Col])
         RowLabelSize = self.grid.GetRowLabelSize()
         ColLabelSize = self.grid.GetRowLabelSize()
         Coor = self.grid.CellToRect(0, Col)

         pos = self.ClientToScreen(((Coor[0]*2 + Coor[2]) // 2 + RowLabelSize - 150, Coor[1] + ColLabelSize //2))
         self.Dia = DiaTableFliter(self.grid, pos=pos, data=ColData)
         self.Dia.Show()
         self.Dia.HideRows = self.HideRows
         self.Dia.OnActive = self.OnActive
         self.Dia.Col = Col
         

   def OnSearch(self, event):
      Data = self.table.GetData()
      ColNum = len(self.table.cols)
      RowNum = len(self.table.rows)
      if self.LastFindLoc is not None and event.GetEventType() == wx.EVT_TEXT.typeId:
         return
      if self.LastFindLoc is None:
         StartRow = 0
         StartCol = -1
      else:
         StartRow = self.LastFindLoc[0]
         StartCol = self.LastFindLoc[1]
         if StartCol == ColNum:
            StartRow += 1
            StartCol = -1
         else:
            StartCol += 1

      for row in range(StartRow, RowNum):
         for col in range(ColNum):
            if row == StartRow and col <= StartCol:
               continue

            if self.SearchCtrl.IsCheckCapital:
               SCValue = self.SearchCtrl.GetValue()
               CellData = Data[row][col]
            else:
               SCValue = str(self.SearchCtrl.GetValue()).upper()
               CellData = str(Data[row][col]).upper()

            if self.SearchCtrl.IsCheckAll:
               if SCValue == CellData:
                  MatchResult = True
               else:
                  MatchResult = False
            else:
               if SCValue in CellData:
                  MatchResult = True
               else:
                  MatchResult = False

            if MatchResult:
               self.grid.GoToCell(row, col)
               self.grid.SelectBlock(row, col, row, col)
               self.LastFindLoc = (row, col)
               if row == RowNum - 1 and col == ColNum -1:
                  self.LastFindLoc = None
               return
            
            if row == RowNum - 1 and col == ColNum -1:
               if self.LastFindLoc is None:
                  dia = wx.MessageDialog(self, '未找到匹配项',
                    caption='警告',style=wx.OK|wx.ICON_WARNING)
                  dia.ShowModal()
                  dia.Destroy()
                  return
               else:
                  self.LastFindLoc = None
                  self.OnSearch(event)

   def changelabelsize(self, grid, *args, **kwargs):
      # 修改标签宽度/长度
      # 修改方法为 rows={x:y} x为第x列 y为大小
      rows = kwargs.get('rows', [])
      cols = kwargs.get('cols', [])
      if rows is not None and len(rows) != 0:
         for i in rows:
            grid.SetRowSize(i, rows[i])
      if cols is not None and len(cols) != 0:
         for i in cols:
            grid.SetColSize(i, cols[i])

   def setdata(self, data):
      # data 为 list 与 list 嵌套 内层list为行数据
      if len(data) > 30:
         self.table.AppendRows(len(data)-29)
      
      for row, rowdata in enumerate(data):
         for col, value in enumerate(rowdata):
            self.table.SetValue(row, col, value)

   def getgrid(self):
      return self.grid

   def getpanel(self):
      return self

   def GetData(self):
      return self.table.GetData()
   
   def SetData(self, data):
      self.table.SetData(data)

   def SamePop(self):
      self.popupmenu = wx.Menu()
      item = self.popupmenu.Append(-1, '复制')
      self.grid.Bind(wx.EVT_MENU, self.OnCopy, item)

   def table1pop(self):
      self.SamePop()
      self.popupmenu.AppendSeparator()
      item = self.popupmenu.Append(-1, '修改表一费率')
      self.Bind(wx.EVT_MENU, self.OnTable1SetRates, item)
   
   def table2pop(self):
      self.SamePop()
      self.popupmenu.AppendSeparator()
      item = self.popupmenu.Append(-1, '添加\\修改措施费')
      item2 = self.popupmenu.Append(-1, '删除措施费')
      if self.name == '表二':
         item3 = self.popupmenu.Append(-1, '修改费率')
      # item4 = self.popupmenu.Append(-1, '修改计算公式')

      self.Bind(wx.EVT_MENU, self.OnTable2Add, item)
      self.Bind(wx.EVT_MENU, self.OnTable2Del, item2)
      if self.name == '表二':
         self.Bind(wx.EVT_MENU, self.OnChangeRate, item3)
   
   def table3pop(self):
      self.SamePop()
      self.popupmenu.AppendSeparator()
      item = self.popupmenu.Append(-1, '插入定额')
      item2 = self.popupmenu.Append(-1, '删除定额')
      item3 = self.popupmenu.Append(-1, '修改定额')
      item4 = self.popupmenu.Append(-1, '上移定额')
      item5 = self.popupmenu.Append(-1, '下移定额')

      self.Bind(wx.EVT_MENU, self.OnTable3Add, item)
      self.Bind(wx.EVT_MENU, self.OnTable3Del, item2)
      self.Bind(wx.EVT_MENU, self.OnTable3Change, item3)
      self.Bind(wx.EVT_MENU, self.OnDatasUp, item4)
      self.Bind(wx.EVT_MENU, self.OnDatasDown, item5)
   
   def table3BCpop(self):
      self.SamePop()
      self.popupmenu.AppendSeparator()
   
      item1 = self.popupmenu.Append(-1, '删除定额')
      item2 = self.popupmenu.Append(-1, '修改定额')
      item3 = self.popupmenu.Append(-1, '上移定额')
      item4 = self.popupmenu.Append(-1, '下移定额')

      self.Bind(wx.EVT_MENU, self.OnTable3BCDel, item1)
      self.Bind(wx.EVT_MENU, self.OnTable3BCChange, item2)
      self.Bind(wx.EVT_MENU, self.OnDatasUp, item3)
      self.Bind(wx.EVT_MENU, self.OnDatasDown, item4)

   def table4pop(self):
      self.SamePop()
      self.popupmenu.AppendSeparator()
   
      item1 = self.popupmenu.Append(-1, '添加材料...')
      item2 = self.popupmenu.Append(-1, '修改材料...')
      item3 = self.popupmenu.Append(-1, '删除材料')
      item4 = self.popupmenu.Append(-1, '上移材料')
      item5 = self.popupmenu.Append(-1, '下移材料')
      item6 = self.popupmenu.Append(-1, '修改运输费率...')
      # item7 = self.popupmenu.Append(-1, '修改运输费率...')
      
      self.Bind(wx.EVT_MENU, self.OnTable4Add, item1)
      self.Bind(wx.EVT_MENU, self.OnTable4DataChange, item2)
      self.Bind(wx.EVT_MENU, self.OnTable4Del, item3)
      self.Bind(wx.EVT_MENU, self.OnTable4DatasUp, item4)
      self.Bind(wx.EVT_MENU, self.OnTable4DatasDown, item5)
      self.Bind(wx.EVT_MENU, self.OnTable4ChangeRate, item6)
   #    self.Bind(wx.EVT_MENU, self.OnTableTest, item7)

   # def OnTableTest(self, event):
   #    print(self.GetData())
   
   def table5pop(self):
      self.SamePop()
      self.popupmenu.AppendSeparator()
      
      item1 = self.popupmenu.Append(-1, '添加费用...')
      item2 = self.popupmenu.Append(-1, '修改本行...')
      item3 = self.popupmenu.Append(-1, '修改费率...')
      item4 = self.popupmenu.Append(-1, '删除本行')
      item5 = self.popupmenu.Append(-1, '上移本行')
      item6 = self.popupmenu.Append(-1, '下移本行')

      self.Bind(wx.EVT_MENU, self.OnTable5AddData, item1)
      self.Bind(wx.EVT_MENU, self.OnTable5ChangeData, item2)
      self.Bind(wx.EVT_MENU, self.OnTable5ChangeRate, item3)
      self.Bind(wx.EVT_MENU, self.OnTable5Del, item4)
      self.Bind(wx.EVT_MENU, self.OnTable5DatasUp, item5)
      self.Bind(wx.EVT_MENU, self.OnTable5DatasDown, item6)

   def OnCopy(self, event):
      row = self.gridevent.GetRow()
      col = self.gridevent.GetCol()

      clipboard = wx.TextDataObject()
      
      sblocks = list(self.grid.GetSelectedBlocks())
      if len(sblocks) == 0:
         clipdata = self.grid.GetCellValue(row, col)
         clipboard.SetText(clipdata)
      elif len(sblocks) == 1:
         sblocks = sblocks[0].Get()
         rows = range(sblocks[0], sblocks[2] + 1)
         cols = range(sblocks[1], sblocks[3] + 1)
         string = ''
         for row in rows:
            for col in cols:
               string += self.grid.GetCellValue(row, col)
               if col != cols[-1]:
                  string += '\t'
            string += '\n'
         clipboard.SetText(string)
      else:
         message = '不能对多重选定区域使用此命令'
         dlg = wx.MessageDialog(self, message, caption='无法复制',
              style=wx.OK|wx.CENTRE)
         dlg.ShowModal()
         dlg.Destroy()
         return

      if wx.TheClipboard.Open():
         wx.TheClipboard.SetData(clipboard)
         wx.TheClipboard.Close()
      else:
         message = '系统无法打卡粘贴板'
         dlg = wx.MessageDialog(self, message, caption='无法复制',
            style=wx.OK|wx.CENTRE)
         dlg.ShowModal()
         dlg.Destroy()
   
   def OnTable1SetRates(self, event):
      Rates = self.Table1GetRates()
      Dia = DiaTable1ChangeRates(self, '调整表一费率', data=Rates)
      Rates = Dia.ShowModal()
      if Rates != 5101:
         self.Table1SetRates(Rates)
      Dia.Destroy()

   def OnTable2Add(self, event):
      forbidnames = [
                     '文明施工费', '工地器材搬运费', '工程干扰费',
                     '工程点交、场地清理费', '临时设施费', '工程车辆使用费',
                     '夜间施工增加费', '冬雨季施工增加费', '生产工具用具使用费',
                     '施工用水电蒸汽费', '特殊地区施工增加费', '已完工程及设备保护费',
                     '运土费', '施工队伍调遣费', '大型施工机械调遣费',
                     ]
      row = self.gridevent.GetRow()
      col = self.gridevent.GetCol()
      value = self.grid.GetCellValue(row, col)
      if value in forbidnames:
         data = self.table2get(value)
         dialog = DiaTable2add(self, '添加措施费', data=data, namefrz=1)
      else:
         dialog = DiaTable2add(self, '添加措施费')
      ret = dialog.ShowModal()
      if ret != 5101:
         self.table2add(ret)
      self.initiable2()
      self.refreshtable2()
      dialog.Destroy()

   def OnTable2Del(self, event):
      forbidnames = [
                     '文明施工费', '工地器材搬运费', '工程干扰费',
                     '工程点交、场地清理费', '临时设施费', '工程车辆使用费',
                     '夜间施工增加费', '冬雨季施工增加费', '生产工具用具使用费',
                     '施工用水电蒸汽费', '特殊地区施工增加费', '已完工程及设备保护费',
                     '运土费', '施工队伍调遣费', '大型施工机械调遣费',
                     ]
      row = self.gridevent.GetRow()
      col = self.gridevent.GetCol()
      value = self.grid.GetCellValue(row, col)
      if value in self.ratedata['直接费']['措施费'] and value not in forbidnames:
         self.table2del(value)
         self.initiable2()
         self.refreshtable2()
      elif value in forbidnames:
         message = '无法删除此措施费'
         dlg = wx.MessageDialog(self, message, caption='无法删除',
              style=wx.OK|wx.CENTRE)
         dlg.ShowModal()
         dlg.Destroy()

   def OnChangeRate(self, event):
      dialog = DiaTable2Rate(self, '调整预算费率', rate=self.ratedata,
         discount=self.discount, contax=self.contax, custom=self.ratedisable,
         matetax=self.matetax,servtax=self.servtax,mach_dis=self.mach_dis,
         ton=self.ton, sc2en_dis=self.sc2en_dis)
      ret = dialog.ShowModal()
      if ret != 5101:
         self.discount = ret['折扣']['施工折扣']
         self.contax = ret['税率']['施工税率']
         self.matetax = ret['税率']['材料税率']
         self.servtax = ret['税率']['服务税率']
         self.ratedata = ret['费率']
         self.ratedisable = ret['自定义']
         self.sc2en_dis = ret['基础数据']['工地距离']
         self.mach_dis = ret['基础数据']['大型机械距离']
         self.ton = ret['基础数据']['大型机械吨位']
         self.PostTable3ChangeEvent()
         self.initiable2()
         self.refreshtable2()
      dialog.Destroy()

   def OnTable3Add(self, event):
      path = os.path.join(BASE_DIR, 'db/quota.db')
      dialog = DiaTable3add(self, '新增定额', path=path)
      row = self.gridevent.GetRow()
      ret = dialog.ShowModal()
      if ret != 5101:
         self.AddTable3Qutoa(ret, row)
      dialog.Destroy()

   def OnTable3Del(self, event):
      row = self.gridevent.GetRow()
      sblocks = list(self.grid.GetSelectedBlocks())

      if len(sblocks) == 0:
         self.DelTable3Qutoas([row])
      elif len(sblocks) == 1:
         sblocks = sblocks[0].Get()
         rowsgen = lambda x,y: list(range(x, y+1))
         rows = rowsgen(sblocks[0], sblocks[2])
         self.DelTable3Qutoas(rows)
      else:
         message = '不能对多重选定区域使用此命令'
         dlg = wx.MessageDialog(self, message, caption='无法复制',
              style=wx.OK|wx.CENTRE)
         dlg.ShowModal()
         dlg.Destroy()
         
      return

   def OnTable3Change(self, event):
      row = self.gridevent.GetRow()
      sblocks = list(self.grid.GetSelectedBlocks())

      if len(sblocks) == 0:
         data = self.ExportTable3Data(row)
         datas = [data]
         dialog = DiaTable3Change(self, '修改定额',datas = datas)
         ret = dialog.ShowModal()
         dialog.Destroy()
      elif len(sblocks) == 1:
         sblocks = sblocks[0].Get()
         rows = range(sblocks[0], sblocks[2] + 1)
         datas = []
         for row in rows:
            datas.append(self.ExportTable3Data(row))
         dialog = DiaTable3Change(self, '修改定额',datas = datas)
         ret = dialog.ShowModal()
         dialog.Destroy()
      else:
         message = '不能对多重选定区域使用此命令'
         dlg = wx.MessageDialog(self, message, caption='无法复制',
              style=wx.OK|wx.CENTRE)
         ret = dlg.ShowModal()
         dlg.Destroy()
      if ret != 5101:
         self.UpdateTable3Datas(ret)

   def OnDatasUp(self, event):
      row = self.gridevent.GetRow()
      sblocks = list(self.grid.GetSelectedBlocks())

      if len(sblocks) == 0:
         self.DataRowUp(self.name, row)
         self.grid.ForceRefresh()
      elif len(sblocks) == 1:
         sblocks = sblocks[0].Get()
         sblocks = list(sblocks)
         for row in range(sblocks[0], sblocks[2] + 1):
            if row == 0:
               return
            self.DataRowUp(self.name, row)
         sblocks[0] = sblocks[0] - 1
         sblocks[2] = sblocks[2] - 1
         self.grid.SelectBlock(*sblocks)
         self.grid.ForceRefresh()
      else:
         message = '不能对多重选定区域使用此命令'
         dlg = wx.MessageDialog(self, message, caption='无法复制',
              style=wx.OK|wx.CENTRE)
         dlg.ShowModal()
         dlg.Destroy()

   def OnDatasDown(self, event):
      row = self.gridevent.GetRow()
      sblocks = list(self.grid.GetSelectedBlocks())

      if len(sblocks) == 0:
         self.DataRowDown(self.name, row)
         self.grid.ForceRefresh()
      elif len(sblocks) == 1:
         sblocks = sblocks[0].Get()
         sblocks = list(sblocks)
         lendata = self.getdatalen(self.name)
         rangelist = list(range(sblocks[0], sblocks[2] + 1))
         rangelist.reverse()
         for row in rangelist:
            if row >= lendata - 1:
               return
            self.DataRowDown(self.name, row)
         sblocks[0] = sblocks[0] + 1
         sblocks[2] = sblocks[2] + 1
         self.grid.SelectBlock(*sblocks)
         self.grid.ForceRefresh()
      else:
         message = '不能对多重选定区域使用此命令'
         dlg = wx.MessageDialog(self, message, caption='无法复制',
              style=wx.OK|wx.CENTRE)
         dlg.ShowModal()
         dlg.Destroy()

   def OnTable3BCDel(self, event):
      row = self.gridevent.GetRow()
      row = self.FromBCGetARows([row], self.name)
      sblocks = list(self.grid.GetSelectedBlocks())

      if len(sblocks) == 0:
         self.DelTable3Qutoas(row)
      elif len(sblocks) == 1:
         sblocks = sblocks[0].Get()
         rowsgen = lambda x,y: list(range(x, y+1))
         rows = rowsgen(sblocks[0], sblocks[2])
         rows = self.FromBCGetARows(rows, self.name)
         self.DelTable3Qutoas(rows)
      else:
         message = '不能对多重选定区域使用此命令'
         dlg = wx.MessageDialog(self, message, caption='无法复制',
              style=wx.OK|wx.CENTRE)
         dlg.ShowModal()
         dlg.Destroy()

   def OnTable3BCChange(self, event):
      row = self.gridevent.GetRow()
      row = self.FromBCGetARows([row], self.name)
      sblocks = list(self.grid.GetSelectedBlocks())

      if len(sblocks) == 0:
         data = self.ExportTable3Data(row[0])
         datas = [data]
         dialog = DiaTable3Change(self, '修改定额',datas = datas)
         ret = dialog.ShowModal()
         dialog.Destroy()
      elif len(sblocks) == 1:
         sblocks = sblocks[0].Get()
         rowsgen = lambda x,y: list(range(x, y+1))
         rows = rowsgen(sblocks[0], sblocks[2])
         rows = self.FromBCGetARows(rows, self.name)
         datas = []
         for row in rows:
            datas.append(self.ExportTable3Data(row))
         dialog = DiaTable3Change(self, '修改定额',datas = datas)
         ret = dialog.ShowModal()
         dialog.Destroy()
      else:
         message = '不能对多重选定区域使用此命令'
         dlg = wx.MessageDialog(self, message, caption='无法复制',
              style=wx.OK|wx.CENTRE)
         ret = dlg.ShowModal()
         dlg.Destroy()
      if ret != 5101:
         self.UpdateTable3Datas(ret)

   def OnTable4Add(self, event):
      row = self.gridevent.GetRow()
      dialog = DiaTable4Add(self, '添加材料', name=self.name)
      data = dialog.ShowModal()
      dialog.Destroy()
      if data != 5101:
         self.Table4AddData(data, row)
         self.settable4readonly()

   def OnTable4Del(self, event):
      row = self.gridevent.GetRow()
      sblocks = list(self.grid.GetSelectedBlocks())
      tabledata = self.table.GetData()

      if len(sblocks) == 0:
         if tabledata[row][1:7] != ['', '', '', '', '', '',]:
            self.Table4DelData(row, self.name)
      elif len(sblocks) == 1:
         sblocks = sblocks[0].Get()
         rowsgen = lambda x,y: list(range(x, y+1))
         rows = rowsgen(sblocks[0], sblocks[2])
         rows.reverse()
         for row in rows:
            if tabledata[row][1:7] != ['', '', '', '', '', '',]:
               self.Table4DelData(row, self.name)
      else:
         message = '不能对多重选定区域使用此命令'
         dlg = wx.MessageDialog(self, message, caption='无法复制',
              style=wx.OK|wx.CENTRE)
         dlg.ShowModal()
         dlg.Destroy()

   def OnTable4DatasUp(self, event):
      row = self.gridevent.GetRow()
      sblocks = list(self.grid.GetSelectedBlocks())
      tabledata = self.table.GetData()

      if len(sblocks) == 0:
         if row == 0:
            return
         if tabledata[row][1:7] != ['', '', '', '', '', '',] and tabledata[row-1][1:7] != ['', '', '', '', '', '',]:
            self.DataRowUp(self.name, row)
            self.grid.ForceRefresh()
      elif len(sblocks) == 1:
         sblocks = sblocks[0].Get()
         sblocks = list(sblocks)
         for row in range(sblocks[0], sblocks[2] + 1):
            if row == 0 or tabledata[row-1][1:7] == ['', '', '', '', '', '',]:
               return
            if tabledata[row][1:7] != ['', '', '', '', '', '',] and tabledata[row-1][1:7] != ['', '', '', '', '', '',]:
               self.DataRowUp(self.name, row)
         sblocks[0] = sblocks[0] - 1
         sblocks[2] = sblocks[2] - 1
         self.grid.SelectBlock(*sblocks)
         self.grid.ForceRefresh()
      else:
         message = '不能对多重选定区域使用此命令'
         dlg = wx.MessageDialog(self, message, caption='无法复制',
              style=wx.OK|wx.CENTRE)
         dlg.ShowModal()
         dlg.Destroy()

   def OnTable4DatasDown(self, event):
      row = self.gridevent.GetRow()
      sblocks = list(self.grid.GetSelectedBlocks())
      tabledata = self.table.GetData()

      if len(sblocks) == 0:
         if tabledata[row][1:7] != ['', '', '', '', '', '',] and tabledata[row+1][1:7] != ['', '', '', '', '', '',]:
            self.DataRowDown(self.name, row)
            self.grid.ForceRefresh()
      elif len(sblocks) == 1:
         sblocks = sblocks[0].Get()
         sblocks = list(sblocks)
         lendata = self.getdatalen(self.name)
         rangelist = list(range(sblocks[0], sblocks[2] + 1))
         rangelist.reverse()
         for row in rangelist:
            if row >= lendata - 1:
               return
            if tabledata[row][1:7] != ['', '', '', '', '', '',] and tabledata[row+1][1:7] != ['', '', '', '', '', '',]:
               self.DataRowDown(self.name, row)
         sblocks[0] = sblocks[0] + 1
         sblocks[2] = sblocks[2] + 1
         self.grid.SelectBlock(*sblocks)
         self.grid.ForceRefresh()
      else:
         message = '不能对多重选定区域使用此命令'
         dlg = wx.MessageDialog(self, message, caption='无法复制',
              style=wx.OK|wx.CENTRE)
         dlg.ShowModal()
         dlg.Destroy()

   def OnTable4DataChange(self, event):
      row = self.gridevent.GetRow()
      data = self.table.GetData()
      odata = [*data[row][:3], data[row][4], data[row][12]]
      if data[row][1:7] == ['', '', '', '', '', '',]:
         return
      dialog = DiaTable4Change(self, '修改材料' ,name=self.name, data=odata)
      cdata = dialog.ShowModal()
      if cdata != 5101:
         self.Table4ChangeData(odata, cdata, row)
      dialog.Destroy()

   def OnTable4ChangeRate(self, event):
      rate = self.Table4GetRate()
      dia = DiaTable4ChangeRates(self, '修改运输运保费费率', data=rate, path=BASE_DIR)
      ret = dia.ShowModal()
      dia.Destroy()
      if ret != 5101:
         self.Table4SetRate(ret)
      

   def OnTable5AddData(self, event):
      row = self.gridevent.GetRow()
      data = self.table.GetData()
      taxs = self.GetTaxs()
      tablelen = 0
      for rowv in data:
         tablelen += 1
         if rowv[0] == '总计':
            break
      
      if row < tablelen:
         addrow = row
      else:
         addrow = tablelen - 1

      dialog = DiaTable5Add(self, '添加费用', taxs=taxs)
      data = dialog.ShowModal()
      dialog.Destroy()

      forbidnames = ['勘察设计费', '勘察费', '设计费',
                     '建设工程监理费', '安全生产费',
                     '审计费', '总计',]

      if data != 5101:
         if data[0] not in forbidnames:
            tax = Dec(data[2]) * Dec(data[3])
            tprice = tax + Dec(data[2])
            data2 = [*data[:3], str(float(tax)), str(float(tprice))]
            self.Table5AddData(data2, addrow)
         else:
            return


   def OnTable5ChangeData(self, event):
      row = self.gridevent.GetRow()
      data = self.table.GetData()
      taxs = self.GetTaxs()
      forbidennames = ['勘察设计费', '勘察费', '设计费',
                       '建设工程监理费', '安全生产费', '审计费',
                       '总计']
      tablelen = 0
      for rowv in data:
         tablelen += 1
         if rowv[0] == '总计':
            break

      if row >= tablelen - 1 or data[row][0] in forbidennames:
         message = '本列无法修改'
         dlg = wx.MessageDialog(self, message, caption='无法复制',
              style=wx.OK|wx.CENTRE)
         dlg.ShowModal()
         dlg.Destroy()
         return
      
      name = data[row][0]
      dis = data[row][1]
      try:
         price = Dec(data[row][2])
         tax = Dec(data[row][3])
         taxrate = tax/price
      except decimal.InvalidOperation:
         price = Dec('0')
         tax = Dec('0')
         taxrate = Dec('0')

      data = [name, dis, str(float(price)), str(float(taxrate))]
      dialog = DiaTable5Add(self, '修改费用', datas=data, taxs=taxs)
      data = dialog.ShowModal()
      dialog.Destroy()
      if data != 5101:
         tax = Dec(data[2]) * Dec(data[3])
         tprice = tax + Dec(data[2])
         data2 = [*data[:3], str(float(tax)), str(float(tprice))]
         self.Table5ChangeData(data2, row)

   def OnTable5ChangeRate(self, event):
      datas = self.Table5GetRate()
      dialog = DiaTable5ChangeRate(self, '表五费率', datas=datas)
      datas = dialog.ShowModal()
      dialog.Destroy()
      if datas != 5101:
         self.Table5ChangeRate(datas)
         
   def OnTable5Del(self, event):
      row = self.gridevent.GetRow()
      sblocks = list(self.grid.GetSelectedBlocks())
      tabledata = self.table.GetData()
      forbidnames = ['勘察设计费', '勘察费', '设计费',
                     '建设工程监理费', '安全生产费',
                     '审计费', '总计',]

      if len(sblocks) == 0:
         if tabledata[row][0:6] != ['', '', '', '', '', '',] and tabledata[row][0] != '总计'\
            and tabledata[row][0] not in forbidnames:
            self.Table5Del(row)
      elif len(sblocks) == 1:
         sblocks = sblocks[0].Get()
         rowsgen = lambda x,y: list(range(x, y+1))
         rows = rowsgen(sblocks[0], sblocks[2])
         rows.reverse()
         for row in rows:
            if tabledata[row][0:6] != ['', '', '', '', '', '',] and tabledata[row][0] != '总计'\
               and tabledata[row][0] not in forbidnames:
               self.Table5Del(row)
      else:
         message = '不能对多重选定区域使用此命令'
         dlg = wx.MessageDialog(self, message, caption='无法复制',
              style=wx.OK|wx.CENTRE)
         dlg.ShowModal()
         dlg.Destroy()
      if tabledata[row][0] in forbidnames:
         message = '本列无法删除！'
         dlg = wx.MessageDialog(self, message, caption='无法删除',
              style=wx.OK|wx.CENTRE)
         dlg.ShowModal()
         dlg.Destroy()

   def OnTable5DatasUp(self, event):
      row = self.gridevent.GetRow()
      sblocks = list(self.grid.GetSelectedBlocks())
      tabledata = self.table.GetData()

      if len(sblocks) == 0:
         if row == 0:
            return
         if tabledata[row][0:6] != ['', '', '', '', '', '',] and tabledata[row-1][0:6] != ['', '', '', '', '', '',]\
            and tabledata[row][0] != '总计':
            self.DataRowUp(self.name, row)
            self.grid.ForceRefresh()
      elif len(sblocks) == 1:
         sblocks = sblocks[0].Get()
         sblocks = list(sblocks)
         for row in range(sblocks[0], sblocks[2] + 1):
            if row == 0 or tabledata[row][0:6] == ['', '', '', '', '', '',] or tabledata[row][0] == '总计':
               return
            if tabledata[row][0:6] != ['', '', '', '', '', '',] and tabledata[row-1][0:6] != ['', '', '', '', '', '',]:
               self.DataRowUp(self.name, row)
         sblocks[0] = sblocks[0] - 1
         sblocks[2] = sblocks[2] - 1
         self.grid.SelectBlock(*sblocks)
         self.grid.ForceRefresh()
      else:
         message = '不能对多重选定区域使用此命令'
         dlg = wx.MessageDialog(self, message, caption='无法复制',
              style=wx.OK|wx.CENTRE)
         dlg.ShowModal()
         dlg.Destroy()

   def OnTable5DatasDown(self, event):
      row = self.gridevent.GetRow()
      sblocks = list(self.grid.GetSelectedBlocks())
      tabledata = self.table.GetData()
      lendata = 0
      for rowv in tabledata:
         lendata += 1
         if rowv[0] == '总计':
            break

      if len(sblocks) == 0:
         if tabledata[row][0:6] != ['', '', '', '', '', '',] and tabledata[row+1][0:6] != ['', '', '', '', '', '',]\
            and tabledata[row][0] != '总计' and tabledata[row+1][0] != '总计':
            self.DataRowDown(self.name, row)
            self.grid.ForceRefresh()
      elif len(sblocks) == 1:
         sblocks = sblocks[0].Get()
         sblocks = list(sblocks)
         rangelist = list(range(sblocks[0], sblocks[2] + 1))
         rangelist.reverse()
         for row in rangelist:
            if row >= lendata - 1:
               return
            if tabledata[row][0:6] != ['', '', '', '', '', '',] and tabledata[row+1][0:6] != ['', '', '', '', '', '',]\
               and tabledata[row][0] != '总计' and tabledata[row+1][0] != '总计':
               self.DataRowDown(self.name, row)
         sblocks[0] = sblocks[0] + 1
         sblocks[2] = sblocks[2] + 1
         self.grid.SelectBlock(*sblocks)
         self.grid.ForceRefresh()
      else:
         message = '不能对多重选定区域使用此命令'
         dlg = wx.MessageDialog(self, message, caption='无法复制',
              style=wx.OK|wx.CENTRE)
         dlg.ShowModal()
         dlg.Destroy()

   def table2add(self, data):
      self.ratedisc.append(['', data['费用名称'], data['费用公式'], data['费用描述']])
      self.ratedata['直接费']['措施费'].update({data['费用名称']: data['费用费率']*100})

   def table2get(self, name):
      ret = ['0', '0', '0', '0']
      ret[0] = name
      for row in self.ratedisc:
         if row[1] == name:
            ret[2] = row[3]
            ret[3] = row[2]
      for key in self.ratedata['直接费']['措施费']:
         if key == name:
            ret[1] = self.ratedata['直接费']['措施费'][key]
      
      return ret
   
   def table2del(self, name):
      if self.ratedata['直接费']['措施费'].get(name) is not None:
         self.ratedata['直接费']['措施费'].pop(name)
         for row, rowv in enumerate(self.ratedisc):
            if rowv[1] == name:
               self.ratedisc.pop(row)

   def OnShowPopmenu(self, event):
      pos = event.GetPosition()
      # pos = self.ScreenToClient(pos)
      self.gridevent = event
      
      self.grid.PopupMenu(self.popupmenu, pos)

   def InitPop(self):
      if self.name in ['表一']:
         self.table1pop()
      elif self.name in ['表二', '表二（标）']:
         self.table2pop()
      elif self.name in ['表三甲']:
         self.table3pop()
      elif self.name in ['表三乙', '表三丙']:
         self.table3BCpop()
      elif self.name in ['表四设备', '表四材料']:
         self.table4pop()
      elif self.name in ['表五']:
         self.table5pop()
      else:
         pass

if __name__ == "__main__":
   class TestFrame(wx.Frame):
      def __init__(self, parent, title):
         super().__init__(parent, size = (1000,600))  
         self.InitUI()

      def InitUI(self):    
         panel = MainPanel(self)
      # sizer = wx.BoxSizer()
      # sizer.Add(panel, wx.EXPAND)
      # self.SetSizer(sizer)
      # self.Fit()


   class MainPanel(wx.Panel):
      def __init__(self, parent):
         super().__init__(parent, size=(1000, 600))
         self.InitUI()

      def InitUI(self):
         sizer = wx.BoxSizer(wx.VERTICAL)   
         self.nb = wx.Notebook(self,style=wx.NB_BOTTOM|wx.NB_FIXEDWIDTH)
         tablelist = [Table_1(), Table_2(), Table_3(), Table_3_2(), Table_4(), Table_5(),]
         for index, i in enumerate(tablelist):
            self.nb.AddPage(BudgetPanel(self.nb, i, i), '表' + str(index+1))
         self.Centre()
         self.Show(True)
         Btn = wx.Button(self, -1, '123')
         sizer.Add(Btn, 0, wx.ALL, 5)
         sizer.Add(self.nb, 1, wx.EXPAND, 0)
         self.SetSizer(sizer)
         self.Fit()
         self.Bind(wx.EVT_BUTTON, self.OnPush, Btn)
      
      def OnPush(self, event):
         Panel = self.nb.GetCurrentPage()
         if Panel.sizer.IsShown(0):
               Panel.sizer.Hide(0)
         else:
               Panel.sizer.Show(0)
         Panel.sizer.Layout()

   app = wx.App()
   frame = TestFrame(None, 'test')
   frame.Show()
   app.MainLoop()


